<?php
/**
 * Created by PhpStorm.
 * User: Season
 * Date: 2018/10/25
 * Time: 15:25
 */

namespace app\api\service;


use app\lib\enum\OrderStatusEnum;
use app\lib\exception\OrderExcption;
use app\lib\exception\TokenException;
use think\Exception;
use app\api\service\Order as OrderService;
use app\api\model\Order as OrderModel;
use think\Loader;
use think\Log;

Loader::import ('WxPay.WxPay',EXTEND_PATH,'.Api.php');
class Pay
{
    private $orderID;
    private $orderNO;

    function __construct ($orderID)
    {
        if(!$orderID){
            throw new Exception('订单号不能为空');
        }
        $this->orderID = $orderID;
    }

    public function pay()
    {
        $this->checkOrderValid ();
        $orderService = new OrderService();
        $status = $orderService->checkOrderStock ($this->orderID);
        if(!$status['pass']){
            return $status;
        }
        return $this->makeWxPreOrder ($status['orderPrice']);
    }

    private function makeWxPreOrder($totalPrice)
    {
        //openid
        $openid = Token::getCurrentTokenVar ('openid');
        if(!$openid){
            throw new TokenException();
        }
        $wxOrderData = new \WxPayUnifiedOrder();
        $wxOrderData->SetOut_trade_no ($this->orderNO);
        $wxOrderData->SetTrade_type ('JSAPI');
        $wxOrderData->SetTotal_fee ($totalPrice*100);//单位分
        $wxOrderData->SetBody ('ambaby母婴生活馆');
        $wxOrderData->SetOpenid ($openid);
        $wxOrderData->SetNotify_url (config ('secure.pay_back_url'));
        return $this->getPaySignature ($wxOrderData);
    }

    private function getPaySignature($wxOrderData)
    {
        $config = new \WxPayConfig();
        $wxOrder = \WxPayApi::unifiedOrder ($config,$wxOrderData);
        if($wxOrder['return_code'] != 'SUCCESS' || $wxOrder['result_code'] !='SUCCESS'){
            Log::record($wxOrder,'error');
            Log::record('获取预支付订单失败','error');
            throw new Exception('获取预支付订单失败');
        }
        //prepay_id
        $this->recordPreOrder($wxOrder);
        $signature = $this->sign ($wxOrder);

        return $signature;
    }

    private function sign($wxOrder){
        $timeStamp = time ();
        $config = new \WxPayConfig();
        $jsApiData = new \WxPayJsApiPay();
        $jsApiData->SetAppid ($config->GetAppId ());
        $jsApiData->SetTimeStamp ((string)$timeStamp);
        //生成随机数
        $rand = md5($timeStamp . mt_rand (0, 1000));
        $jsApiData->SetNonceStr ($rand);

        $jsApiData->SetPackage ('prepay_id='.$wxOrder['prepay_id']);
        $jsApiData->SetSignType ('md5');

        $sign = $jsApiData->MakeSign ();
        $rawValuews = $jsApiData->GetValues ();
        $rawValuews['paySign'] = $sign;

        unset($rawValuews['appId']);

        return $rawValuews;
    }

    private function recordPreOrder($wxOrder){
        OrderModel::where('id', '=', $this->orderID)
            ->update(['prepay'=>$wxOrder['prepay_id']]);
    }

    private function checkOrderValid()
    {
        $order = OrderModel::where('id', '=', $this->orderID)
            ->find ();
        if(!$order){
            throw new OrderExcption();
        }
        if(!Token::isValidOperate ($order->user_id)){
            throw new TokenException(
                [
                    'msg' => '订单与用户不匹配',
                    'errorCode' => 10003
                ]);
        }
        if($order->status != OrderStatusEnum::UNPAID ){
            throw new OrderExcption(
                [
                    'msg'=>'订单已支付',
                    'errorCode'=>80003,
                    'code'=>400
                ]);
        }
        $this->orderNO = $order->order_no;
        return true;
    }
}